/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { BaseMatcher } from '../BaseMatcher.js';
/**
 * Is the value equal to another value, as tested by the
 * {@link java.lang.Object#equals} invokedMethod?
 */
export class IsEqual extends BaseMatcher {
    constructor(equalArg) {
        super();
        this.expectedValue = equalArg;
    }
    matches(actualValue) {
        return IsEqual.areEqual(actualValue, this.expectedValue);
    }
    describeTo(description) {
        description.appendValue(this.expectedValue);
    }
    static areEqual(actual, expected) {
        if (actual == null) {
            return expected == null;
        }
        if (expected != null && Array.isArray(actual)) {
            return Array.isArray(expected) && IsEqual.areArraysEqual(actual, expected);
        }
        return actual == expected;
    }
    static areArraysEqual(actualArray, expectedArray) {
        return IsEqual.areArrayLengthsEqual(actualArray, expectedArray) && IsEqual.areArrayElementsEqual(actualArray, expectedArray);
    }
    static areArrayLengthsEqual(actualArray, expectedArray) {
        return actualArray.length == expectedArray.length;
    }
    static areArrayElementsEqual(actualArray, expectedArray) {
        for (let i = 0; i < actualArray.length; i++) {
            if (!IsEqual.areEqual(actualArray[i], expectedArray[i])) {
                return false;
            }
        }
        return true;
    }
    /**
       * Creates a matcher that matches when the examined object is logically equal to the specified
       * <code>operand</code>, as determined by calling the {@link java.lang.Object#equals} method on
       * the <b>examined</b> object.
       *
       * <p>If the specified operand is <code>null</code> then the created matcher will only match if
       * the examined object's <code>equals</code> method returns <code>true</code> when passed a
       * <code>null</code> (which would be a violation of the <code>equals</code> contract), unless the
       * examined object itself is <code>null</code>, in which case the matcher will return a positive
       * match.</p>
       *
       * <p>The created matcher provides a special behaviour when examining <code>Array</code>s, whereby
       * it will match if both the operand and the examined object are arrays of the same length and
       * contain items that are equal to each other (according to the above rules) <b>in the same
       * indexes</b>.</p>
       * For example:
       * <pre>
       * assertThat("foo", equalTo("foo"));
       * assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
       * </pre>
       *
       * @param <T>
       *     the matcher type.
       * @param operand
       *     the value to check.
       * @return The matcher.
       */
    static equalTo(operand) {
        return new IsEqual(operand);
    }
    /**
       * Creates an {@link org.hamcrest.core.IsEqual} matcher that does not enforce the values being
       * compared to be of the same static type.
       *
       * @param operand
       *     the value to check.
       * @return The matcher.
       */
    static equalToObject(operand) {
        return new IsEqual(operand);
    }
}
